package network

import (
	"net"
	"sync"
	"sync/atomic"
)

const (
	ID_TCPHEADER_LENGTH          = 4           // 包头长度
	ID_DATA_MAX_LENGTH           = 1024 * 1024 // 消息体最大长度
	ID_READ_CHAN_LENGTH          = 10240       // 读管道大小
	ID_CLIENT_WRITE_CHAN_LENGTH  = 1024        // 被动连接写管道大小
	ID_CONNECT_WRITE_CHAN_LENGTH = 10240       // 主动连接写管道大小
	ID_TCP_RECONNECT_TIME        = 2           // 重连时间间隔秒

	// 消息类型
	ID_MSG_TYPE_RECV                  = 1 // 数据包
	ID_MSG_TYPE_CLIENT_NEW_CONNECTION = 2 // 被动新连接
	ID_MSG_TYPE_CLIENT_DISCONNECTION  = 3 // 被动连接断开
	ID_MSG_TYPE_CONN_NEW_CONNECTION   = 4 // 主动新连接
	ID_MSG_TYPE_CONN_DISCONNECTION    = 5 // 主动连接断开
)

type GuidType = int64
type RecvPacketType = Packet
type SendPacketType = SendPacket

var (
	incGuid   GuidType
	socketMap sync.Map
	readChan  chan *RecvPacketType = make(chan *RecvPacketType, ID_READ_CHAN_LENGTH)
)

func genGuid() GuidType {
	return atomic.AddInt64(&incGuid, 1)
}

type ISocket interface {
	GetGuid() GuidType
	Close()
	RemoteAddr() string
	SendData(*SendPacketType) bool
}

// 监听
type TCPServer struct {
	addr string // "127.0.0.1:888"

	listener   *net.TCPListener
	maxConn    int32 // 最大连接人数
	connectMap sync.Map
	curConnNum int32 // 当前连接人数
}

type TCPSocket struct {
	tCPConn *net.TCPConn
	guid    int64

	syncClose sync.WaitGroup
	writeChan chan *SendPacketType
}

// 被动连接
type TCPClient struct {
	TCPSocket
	ts *TCPServer
}

// 主动连接
type TCPConnect struct {
	TCPSocket
	addr string
}

// 消息包
type Packet struct {
	Ptype byte
	Guid  GuidType
	Addr  string
	Data  []byte // 此容量使用时只能增长不可变小
	slen  int    // pool used
}

// 发送包
type SendPacket struct {
	Guid GuidType
	Data []byte // 此容量使用时只能增长不可变小
	slen int    // pool used
}
